package cs3343.project.family;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.util.HashMap;


/**
 * The Class CardController.
 */
public class CardController {
	
	/** The gc. */
	private GameController gc;
	
	/** The ui controller. */
	private UIController uiController;
	
	/** The event cards. */
	private HashMap<String, EventCard> eventCards;
	
	/** The oral cards. */
	private HashMap<String, OralCard> oralCards;
	
	/** The action cards. */
	private HashMap<String, ActionCard> actionCards;
	
	/** The magic tool cards. */
	private HashMap<String, MagicToolCard> magicToolCards;
	
	/**
	 * Instantiates a new card controller.
	 *
	 * @param gc the gc
	 */
	public CardController(GameController gc) {
		this.gc = gc;
		uiController = this.gc.getUiController();
		
		eventCards = new HashMap<String, EventCard>();
		oralCards = new HashMap<String, OralCard>();
		actionCards = new HashMap<String, ActionCard>();
		magicToolCards = new HashMap<String, MagicToolCard>();
	}
	
	/**
	 * Draw card.
	 *
	 * @param cardType the card type
	 * @return the card
	 */
	public Card drawCard(int cardType) {
		int ranCard = 0;
		switch (cardType) {
			case 1:
				ranCard = (int) (eventCards.size() * Math.random() + 1);
				return eventCards.get(String.valueOf(ranCard));
			case 2:
				ranCard = (int) (magicToolCards.size() * Math.random() + 1);
				return magicToolCards.get(String.valueOf(ranCard));
			case 3:
				ranCard = (int) (actionCards.size() * Math.random() + 1);
				return actionCards.get(String.valueOf(ranCard));
			case 4:
				ranCard = (int) (oralCards.size() * Math.random() + 1);
				return oralCards.get(String.valueOf(ranCard));
			default:
				return null;
		}
	}
	
	/**
	 * Import all card.
	 */
	public void importAllCard() {
		importEventCard();
		importToolCard();
		importActionCard();
		importOralCard();
	}
	
	/**
	 * Import event card.
	 */
	public void importEventCard() {
		String result[];
		try {
	        BufferedReader infile = new BufferedReader(new InputStreamReader(
	        		new FileInputStream(ConfigManager.getEventCardPath()), "UTF-8"));
	        String str;
	        while ((str = infile.readLine()) != null) {
	        	if (str.length() > 0) {
                    // UTF - 8 BOM CHAR
                    int c = str.charAt(0);
                    if (c == 65279)
                    	str = str.substring(1, str.length());
	        	}
	            result = str.split("\t");
	            
	            EventCard event = new EventCard(result[1], result[2], result[3], result[4], result[5], result[6], result[7], result[8], result[9]);
	            eventCards.put(result[0], event);
	        }
	        infile.close();
	    } 
	    catch (IOException e) {
	    	ConfigManager.saveErrorLog(e.toString());
	    }
	}
	
	/**
	 * Import oral card.
	 */
	public void importOralCard() {
		String result[];
		try {
	        BufferedReader infile = new BufferedReader(new InputStreamReader(
	        		new FileInputStream(ConfigManager.getOralCardPath()), "UTF-8"));
	        String str;
	        while ((str = infile.readLine()) != null) {
	        	if (str.length() > 0) {
                    // UTF - 8 BOM CHAR
                    int c = str.charAt(0);
                    if (c == 65279)
                    	str = str.substring(1, str.length());
	        	}
	            result = str.split("\t");
	            
	            OralCard oral = new OralCard(result[1]);

	            oralCards.put(result[0], oral);
	        }
	        infile.close();
	    } 
	    catch (IOException e) {
	    	ConfigManager.saveErrorLog(e.toString());
	    }
	}
	
	/**
	 * Import action card.
	 */
	public void importActionCard() {
		String result[];
		try {
	        BufferedReader infile = new BufferedReader(new InputStreamReader(
	        		new FileInputStream(ConfigManager.getActionCardPath()), "UTF-8"));
	        String str;
	        while ((str = infile.readLine()) != null) {
	        	if (str.length() > 0) {
                    // UTF - 8 BOM CHAR
                    int c = str.charAt(0);
                    if (c == 65279)
                    	str = str.substring(1, str.length());
	        	}
	            result = str.split("\t");
	            
	            ActionCard action = new ActionCard(result[1]);

	            actionCards.put(result[0], action);
	        }
	        infile.close();
	    } 
	    catch (IOException e) {
	    	ConfigManager.saveErrorLog(e.toString());
	    }
	}
	
	/**
	 * Import tool card.
	 */
	public void importToolCard() {
		String result[];
		try {
	        BufferedReader infile = new BufferedReader(new InputStreamReader(
	        		new FileInputStream(ConfigManager.getToolCardPath()), "UTF-8"));
	        String str;
	        while ((str = infile.readLine()) != null) {
	        	if (str.length() > 0) {
                    // UTF - 8 BOM CHAR
                    int c = str.charAt(0);
                    if (c == 65279)
                    	str = str.substring(1, str.length());
	        	}
	            result = str.split("\t");
	            
	            MagicToolCard tool = new MagicToolCard(result[1], result[2], result[3]);

	            magicToolCards.put(result[0], tool);
	        }
	        infile.close();
	    } 
	    catch (IOException e) {
	    	ConfigManager.saveErrorLog(e.toString());
	    }
	}
	
	/**
	 * Count exist num of card.
	 *
	 * @param index the index
	 * @return the int
	 */
	private static int countExistNumOfCard(int index) {
		int count = 0;
		try {
			BufferedReader infile;
			if (index == 0)
				infile = new BufferedReader(new InputStreamReader(
						new FileInputStream(ConfigManager.ACTIONCARD_ZH_PATH), "UTF-8"));
			else
				infile = new BufferedReader(new InputStreamReader(
						new FileInputStream(ConfigManager.ORALCARD_ZH_PATH), "UTF-8"));
	        String str;
	        
	        while ((str = infile.readLine()) != null) {
	        	if (str.length() > 0) {
                    // UTF - 8 BOM CHAR
                    int c = str.charAt(0);
                    if (c == 65279)
                    	str = str.substring(1, str.length());
	        	}
	        	count++;
	        }
	        infile.close();
	    } 
	    catch (IOException e) {
	    	ConfigManager.saveErrorLog(e.toString());
	    }
		return count;
	}
	
	/**
	 * Creates the card.
	 *
	 * @param index the index
	 * @param zh the zh
	 * @param en the en
	 * @param cn the cn
	 */
	public static void createCard(int index, String zh, String en, String cn) {
		int newID = countExistNumOfCard(index) + 1;
		try	{
			BufferedWriter outfile;
			if (index == 0) {
				outfile = new BufferedWriter(new OutputStreamWriter(
						new FileOutputStream(ConfigManager.ACTIONCARD_ZH_PATH, true), "UTF-8"));
				outfile.newLine();
				outfile.append(String.valueOf(newID) + "\t" + zh);
				outfile.close();
				
				outfile = new BufferedWriter(new OutputStreamWriter(
						new FileOutputStream(ConfigManager.ACTIONCARD_EN_PATH, true), "UTF-8"));
				outfile.newLine();
				outfile.append(String.valueOf(newID) + "\t" + en);
				outfile.close();
				
				outfile = new BufferedWriter(new OutputStreamWriter(
						new FileOutputStream(ConfigManager.ACTIONCARD_CN_PATH, true), "UTF-8"));
				outfile.newLine();
				outfile.append(String.valueOf(newID) + "\t" + cn);
				outfile.close();
			}
			else {
				outfile = new BufferedWriter(new OutputStreamWriter(
						new FileOutputStream(ConfigManager.ORALCARD_ZH_PATH, true), "UTF-8"));
				outfile.newLine();
				outfile.append(String.valueOf(newID) + "\t" + zh);
				outfile.close();
				
				outfile = new BufferedWriter(new OutputStreamWriter(
						new FileOutputStream(ConfigManager.ORALCARD_EN_PATH, true), "UTF-8"));
				outfile.newLine();
				outfile.append(String.valueOf(newID) + "\t" + en);
				outfile.close();
				
				outfile = new BufferedWriter(new OutputStreamWriter(
						new FileOutputStream(ConfigManager.ORALCARD_CN_PATH, true), "UTF-8"));
				outfile.newLine();
				outfile.append(String.valueOf(newID) + "\t" + cn);
				outfile.close();
			}
		}
		catch (IOException e) {
			ConfigManager.saveErrorLog(e.toString());
		}
	}
	
	/**
	 * Gets the event card.
	 *
	 * @param key the key
	 * @return the event card
	 */
	public Card getEventCard(String key) {
		return eventCards.get(key);
	}
	
	/**
	 * Gets the num of event card.
	 *
	 * @return the num of event card
	 */
	public int getNumOfEventCard() {
		return eventCards.size();
	}

	/**
	 * Gets the oral card.
	 *
	 * @param key the key
	 * @return the oral card
	 */
	public Card getOralCard(String key) {
		return oralCards.get(key);
	}
	
	/**
	 * Gets the num of oral card.
	 *
	 * @return the num of oral card
	 */
	public int getNumOfOralCard() {
		return oralCards.size();
	}
	
	/**
	 * Gets the action card.
	 *
	 * @param key the key
	 * @return the action card
	 */
	public Card getActionCard(String key) {
		return actionCards.get(key);
	}
	
	/**
	 * Gets the num of action card.
	 *
	 * @return the num of action card
	 */
	public int getNumOfActionCard() {
		return actionCards.size();
	}
	
	/**
	 * Gets the magic tool card.
	 *
	 * @param key the key
	 * @return the magic tool card
	 */
	public Card getMagicToolCard(String key) {
		return magicToolCards.get(key);
	}
	
	/**
	 * Gets the num of magic tool card.
	 *
	 * @return the num of magic tool card
	 */
	public int getNumOfMagicToolCard() {
		return magicToolCards.size();
	}
	
	//身份大轉移
	/**
	 * Enable exchange character.
	 *
	 * @param character the character
	 */
	public void enableExchangeCharacter(Character character) {
		if (character.getNumOfAvailableCard("SpecialCard", this) > 0)
			uiController.getGameFrame().enableChangeCharButton();
		else
			uiController.getGameFrame().disableChangeCharButton();
	}
	
	/**
	 * Type matched.
	 *
	 * @param card the card
	 * @param type the type
	 * @return true, if successful
	 */
	public boolean typeMatched(Card card, String type) {		
		String toChinese = "";
		if (type.equalsIgnoreCase("OralCard"))
			toChinese = "說話";
		else if (type.equalsIgnoreCase("ActionCard"))
			toChinese = "動作";
		else if (type.equalsIgnoreCase("EventCard"))
			toChinese = "事件";
		else if (type.equalsIgnoreCase("SpecialCard"))
			toChinese = "特殊";
		
		if (card.getOption(0).lastIndexOf(toChinese) != -1)
			return true;
		return false;
	}
}
